/**
 * 可迭代（Iterable） 对象是数组的泛化。这个概念是说任何对象都可以被定制为可在 for..of 循环中使用的对象。
 * next() 方法返回的结果的格式必须是 {done: Boolean, value: any}，当 done=true 时，表示迭代结束，否则 value 是下一个值
 * Iterable 如上所述，是实现了 Symbol.iterator 方法的对象。
Array-like 是有索引和 length 属性的对象，所以它们看起来很像数组。
有一个全局方法 Array.from 可以接受一个可迭代或类数组的值
 */
let range = {
  from: 1,
  to: 5,
  //   [Symbol.iterator]() {
  //     this.current = this.from;
  //     return this;
  //   },

  //   next() {
  //     if (this.current <= this.to) {
  //       return { done: false, value: this.current++ };
  //     } else {
  //       return { done: true };
  //     }
  //   },
};

// 1. for..of 调用首先会调用这个：
range[Symbol.iterator] = function () {
  // ……它返回迭代器对象（iterator object）：
  // 2. 接下来，for..of 仅与此迭代器一起工作，要求它提供下一个值
  return {
    current: this.from,
    last: this.to,

    // 3. next() 在 for..of 的每一轮循环迭代中被调用
    next() {
      // 4. 它将会返回 {done:.., value :...} 格式的对象
      if (this.current <= this.last) {
        return { done: false, value: this.current++ };
      } else {
        return { done: true };
      }
    },
  };
};

// 现在它可以运行了！
// for (let num of range) {
//   console.log(num); // 1, 然后是 2, 3, 4, 5
// }

for (let char of "test") {
  // 触发 4 次，每个字符一次
  //   console.log(char); // t, then e, then s, then t
}

//Array.from 方法接受对象，检查它是一个可迭代对象或类数组对象，然后创建一个新数组，并将该对象的所有元素复制到这个新数组。

// let range = [1, 5, 24];
let arr = Array.from(range, (num) => num * num);

console.log(arr);
